package Chess.Moves;

import Chess.*;
import Chess.Pieces.*;
import Chess.Pieces.Piece.*;

/**
 *	A class representing an EnPassantMove in Chess.
 *
 *	@author		Jeff Chan
 */
public class EnPassantMove extends Move {

	private Piece opposingPiece;
	private Square opposingPieceSquare;
	
	private EnPassantMove(Piece piece, Square startSquare, Square endSquare, Piece opposingPawn,
			Square opposingPawnSquare) {
		super(piece, startSquare, endSquare);
		this.opposingPiece = opposingPawn;
		this.opposingPieceSquare = opposingPawnSquare;
	}

	public static boolean canBeExecuted(Board board, Square startSquare, Square endSquare, Move lastMove) {
		boolean canBeExecuted = false;
		
		Piece piece = board.getPiece(startSquare);
		if (piece != null && PieceType.PAWN.equals(piece.getPieceType())) {
			Pawn pawn = (Pawn) piece;
			if (pawn.canMoveEnPassant(board, startSquare, endSquare)) {
				Piece opposingPawn = board.getPiece(new Square(endSquare.getFile(), startSquare.getRank()));
				if (opposingPawn != null && PieceType.PAWN.equals(opposingPawn.getPieceType()) &&
					lastMove != null && lastMove.getPiece() == opposingPawn && 
					Math.abs(lastMove.getStartSquare().distanceBetweenRank(lastMove.getEndSquare())) == 2) {
					canBeExecuted = true;
				}
			}
		}
		
		return canBeExecuted;
	}

	public static EnPassantMove execute(Board board, Square startSquare, Square endSquare) {
		Piece pawn = board.getPiece(startSquare);
		Square opposingPawnSquare = new Square(endSquare.getFile(), startSquare.getRank());
		Piece opposingPawn = board.getPiece(opposingPawnSquare);
		board.movePiece(pawn, startSquare, endSquare);
		board.removePiece(opposingPawnSquare);
		pawn.incrementMoveCount();
		return new EnPassantMove(pawn, startSquare, endSquare, opposingPawn, opposingPawnSquare);
	}
	
	public MoveType getMoveType() {
		return MoveType.EN_PASSANT;
	}
	
	public void undo(Board board) {
		piece.decrementMoveCount();
		board.movePiece(piece, endSquare, startSquare);
		board.putPiece(opposingPieceSquare, opposingPiece);
	}
	
	public Piece getOpposingPiece() {
		return opposingPiece;
	}
	
	public Square getOpposingPieceSquare() {
		return opposingPieceSquare;
	}

}
